package com.lcx.core.exector;

import com.lcx.core.HandleCore;
import com.lcx.exbean.LogBean;
import com.lcx.util.JsonHandler;
import com.lcx.util.ParseUtil;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;

public class SyncExector {

    private static LogBean logger = LogBean.getLogger(SyncExector.class);

    public String exec(String id,String name,String args) throws Exception{
        Object obj = HandleCore.getJsObject(id);
        Method method = HandleCore.getInvokeMethod(id,name);
        if(obj != null && method != null){
            try{
                Object resultArgs[] = convertArgs(args,method);
                Object result = method.invoke(obj,resultArgs);
                if(result != null){
                    return JsonHandler.toJson(result);
                }
            }catch (Exception e){
                Exception exception=e;
                while(exception instanceof InvocationTargetException){
                    exception= (Exception) ((InvocationTargetException)exception).getTargetException();
                }
                logger.error("js执行器出现异常：",exception);
                throw exception;
            }
        }
        return null;
    }

    /**
     * 转换json中的参数信息
     * @param args
     * @param m
     * @return
     */
    private Object[] convertArgs(String args,Method m) throws Exception{
        Class<?> clazz[] = m.getParameterTypes();
        Type types[] = m.getGenericParameterTypes();
        if(clazz == null || clazz.length == 0) return null;
        List<Object> argList = JsonHandler.parseJson(args,List.class);
        Object []resutArgs = new Object[clazz.length];
        if(argList!= null && !argList.isEmpty()){
            Class<?> type;
            Object oArg;
            String tJson;
            for(int i=0;i<clazz.length;i++){
                if(i<argList.size()){
                    oArg = argList.get(i);
                    if(oArg == null){
                        resutArgs[i]=null;
                        continue;
                    }
                    type = clazz[i];
                    Object argObj = null;

                    if(List.class.isAssignableFrom(type) && types[i] instanceof ParameterizedType){
                        ParameterizedType pt = (ParameterizedType) types[i];
                        tJson = JsonHandler.toJson(oArg);
                        argObj = JsonHandler.parseArrayJson(tJson,Class.forName(pt.getActualTypeArguments()[0].getTypeName()));
                    }else{
                        argObj = ParseUtil.parse(argList.get(i),type,null);
                        if(argObj == null){
                            tJson = JsonHandler.toJson(oArg);
                            argObj = JsonHandler.parseJson(tJson,type);
                        }
                    }
                    resutArgs[i]=argObj;
                }else{
                    resutArgs[i]=null;
                }
            }
        }
        return resutArgs;
    }

}
